<!doctype html><html lang=cn-zh><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="IE=edge"><style type=text/css>body{font-family:monospace}</style><title>[译]python中的global和nonlocal的实践</title>
<meta name=description content="A blog maintained by Vimiix."><link rel=stylesheet href=/css/style.css><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?7c24231917964240bae97e813810620c",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script></head><body><header>====================<br>== Hi, I'm Vimiix ==<br>====================<div style=float:right;color:gray;font-size:x-large>Get hands dirty.</div><br><p><nav><a href=https://www.vimiix.com/><b>首页</b></a>.
<a href=/posts/><b>文章列表</b></a>.
<a href=/projects/><b>开源项目</b></a>.
<a href=/tags/><b>标签</b></a>.
<a href=/friends/><b>友链</b></a>.
<a href=/about/><b>关于我</b></a>.
<a href=/index.xml><b>RSS</b></a>.</nav></p></header><main><article><h1>[译]python中的global和nonlocal的实践</h1><b><time>2017.12.14 18:51</time></b>
<a href=/tags/python>python</a>
<a href=/tags/translation>translation</a>
<a href=/tags/global>global</a>
<a href=/tags/nonlocal>nonlocal</a><div><blockquote><p>今天的博文翻译是关于 python 中 global 和 nonlocal 两个关键字的用法，原文的作者是来自孟加拉国的<a href=https://twitter.com/subeen>Tamim Shahriar</a>，他的<a href="http://love-python.blogspot.com.br/?view=classic">博客</a>非常适合新手朋友去阅读，都是简短而有意义的 python 实践。</p></blockquote><p>我们大多数人都对 Python 中的全局变量很熟悉了。如果我们在一个模块中声明全局变量，模块内部的任何函数都可以访问这个全局变量。（模块可以理解为一个<code>python</code>文件或<code>.py</code>文件）</p><p>例如下面的代码：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span> 	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x)
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>这段代码将会输出：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>inside myfnc <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>inside myfnc2 <span style=color:#ae81ff>5</span>
</span></span></code></pre></div><p>如果我们来改变一下代码，就像下面这样：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span>	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x)
</span></span><span style=display:flex><span>		x <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;x = &#34;</span>, x)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>结果会得到如下错误：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>File <span style=color:#e6db74>&#34;program.py&#34;</span>, line <span style=color:#ae81ff>6</span>, <span style=color:#f92672>in</span> myfnc2
</span></span><span style=display:flex><span>    print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x)
</span></span><span style=display:flex><span><span style=color:#a6e22e>UnboundLocalError</span>: local variable <span style=color:#e6db74>&#39;x&#39;</span> referenced before assignment
</span></span></code></pre></div><p>在函数<code>myfnc2()</code>中一旦声明了<code>x = 10</code>，Python 就会认为<code>x</code>是一个局部变量（译者注：此处涉及到 python 的 BGEL 变量优先级原则，可参考<a href=https://docs.lvrui.io/2016/07/12/Python%E7%9A%84%E5%8F%98%E9%87%8F%E4%BD%9C%E7%94%A8%E5%9F%9F/>此文章</a>了解），而在打印函数时，<code>x</code>在声明之前就使用了它，所有它给出了这个错误。因为局部变量是在编译时才确定的（来自官方文档：“事实上，局部变量已经是静态确定了”）(译者注：对于这句话没法直观的理解，可以继续参考<a href=http://blog.csdn.net/lwl_ls/article/details/1731318>这篇翻译</a>)如果将 x 声明是全局的，则可以排除这个错误。</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span>	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>global</span> x
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x)
</span></span><span style=display:flex><span>		x <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;x = &#34;</span>, x)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>现在你可以再次运行程序，它就不会抛出任何错误。</p><p>如果我们现在这样写呢？</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span>	y <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>global</span> x
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x, y)
</span></span><span style=display:flex><span>		x <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;x = &#34;</span>, x)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>如果你运行该程序，你会看到正确的输出。但是如果要在<code>myfnc2（）</code>中写入 y（例如，指定<code>y = 1</code>之类），则不能使用 <code>global y</code>，因为 y 不是全局变量。你不妨试试下面这个失败的代码：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span>	y <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>global</span> x
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>global</span> y
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x, y)
</span></span><span style=display:flex><span>		x <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;x = &#34;</span>, x)
</span></span><span style=display:flex><span>		y <span style=color:#f92672>=</span> <span style=color:#ae81ff>1</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;y = &#34;</span>, y)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>你会得到这个错误：<code>NameError: name 'y' is not defined</code></p><p>我们需要明白，<code>y</code>不是一个全局变量。这里<code>nonlocal</code>就起作用了！仅仅只需写成<code>nonlocal y</code>来替换<code>global y</code>。它就可以使<code>myfnc2（）</code>中的<code>y</code>正常读写，调用。</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>x <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc</span>():
</span></span><span style=display:flex><span>	print(<span style=color:#e6db74>&#34;inside myfnc&#34;</span>, x)
</span></span><span style=display:flex><span>	y <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>	<span style=color:#66d9ef>def</span> <span style=color:#a6e22e>myfnc2</span>():
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>global</span> x
</span></span><span style=display:flex><span>		<span style=color:#66d9ef>nonlocal</span> y
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;inside myfnc2&#34;</span>, x, y)
</span></span><span style=display:flex><span>		x <span style=color:#f92672>=</span> <span style=color:#ae81ff>10</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;x = &#34;</span>, x)
</span></span><span style=display:flex><span>		y <span style=color:#f92672>=</span> <span style=color:#ae81ff>1</span>
</span></span><span style=display:flex><span>		print(<span style=color:#e6db74>&#34;y = &#34;</span>, y)
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>	myfnc2()
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>myfnc()
</span></span></code></pre></div><p>这是我今天学到的东西。 :)</p><blockquote><p>原文链接：<a href="http://love-python.blogspot.com.br/2017/06/global-and-nonlocal-variable-in-python.html?view=classic">http://love-python.blogspot.com.br/2017/06/global-and-nonlocal-variable-in-python.html?view=classic</a></p><p>译文链接：<a href=http://vimiix.com/post/2017/12/14/global-and-nonlocal-variable-in-Python/>http://vimiix.com/post/2017/12/14/global-and-nonlocal-variable-in-Python/</a></p></blockquote></div></article></main><aside><div><div><h3>LATEST POSTS</h3></div><div><ul><li><a href=/posts/2025-10-16-kubernetes-apiserver-authorization-mechanism/>Kubernetes APIServer 鉴权机制</a></li><li><a href=/posts/2025-09-30-kubernetes-apiserver-authentication-mechanism/>Kubernetes APIServer 认证机制</a></li><li><a href=/posts/2024-12-16-deploy-kubernetes-by-kubeadm/>使用 kubeadm 搭建 kubernetes 集群</a></li><li><a href=/posts/2024-09-20-how-to-code-review/>如何做code review</a></li><li><a href=/posts/2024-08-12-weakref-in-python/>Python中的弱引用</a></li></ul></div></div></aside><footer><p>Social Links:
<a href=https://github.com/vimiix><b>Github</b></a>.
<a href=https://www.douban.com/people/vimiix/><b>Douban</b></a>.
<a href=mailto:i@vimiix.com><b>Email</b></a>.<br><hr>&copy; 2017-2025
Vimiix Yao; All rights reserved.
<a href=https://beian.miit.gov.cn/>京ICP备19015214号-1</a></p><script src=https://l2dwidget.js.org/lib/L2Dwidget.min.js></script><script>L2Dwidget.init({model:{jsonPath:"https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json"}})</script></footer></body></html>